﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Prototype
{
    class Program
    {
        static void Main(string[] args)
        {
            //ConcretePrototype1 p1 = new ConcretePrototype1("I");
            //ConcretePrototype1 c1 = (ConcretePrototype1)p1.Clone();
            //Console.WriteLine("Cloned: {0}", c1.Id);
            //c1.Id = "CloneI";
            //Console.WriteLine("p1.Id is {0}, c1.Id is {1}", p1.Id, c1.Id);

            //ConcretePrototype2 p2 = new ConcretePrototype2("II");
            //ConcretePrototype2 c2 = (ConcretePrototype2)p2.Clone();
            //Console.WriteLine("Cloned: {0}", c2.Id);

            ColorManager colormanager = new ColorManager();

            // Initialize with standard colors
            colormanager["red"] = new Color(255, 0, 0);
            colormanager["green"] = new Color(0, 255, 0);
            colormanager["blue"] = new Color(0, 0, 255);

            // User adds personalized colors
            colormanager["angry"] = new Color(255, 54, 0);
            colormanager["peace"] = new Color(128, 211, 128);
            colormanager["flame"] = new Color(211, 34, 20);

            // User clones selected colors
            Color color1 = colormanager["red"].Clone() as Color;
            Color color2 = colormanager["peace"].Clone() as Color;
            Color color3 = colormanager["flame"].Clone() as Color;

            Console.Read();
        }
    }

    abstract class Prototype
    {
        public Prototype(string id)
        {
            this.Id = id;
        }
        public string Id { get; set; }
        public abstract Prototype Clone();
    }

    class ConcretePrototype1 : Prototype
    {
        public ConcretePrototype1(string id) : base(id) { }

        public override Prototype Clone()
        {
            return this.MemberwiseClone() as Prototype;
        }
    }

    class ConcretePrototype2 : Prototype
    {
        public ConcretePrototype2(string id) : base(id) { }

        public override Prototype Clone()
        {
            return this.MemberwiseClone() as Prototype;
        }
    }

    /// <summary>

    /// The 'Prototype' abstract class

    /// </summary>

    abstract class ColorPrototype
    {

        public abstract ColorPrototype Clone();

    }



    /// <summary>

    /// The 'ConcretePrototype' class

    /// </summary>

    class Color : ColorPrototype
    {

        private int _red;

        private int _green;

        private int _blue;



        // Constructor

        public Color(int red, int green, int blue)
        {

            this._red = red;

            this._green = green;

            this._blue = blue;

        }



        // Create a shallow copy

        public override ColorPrototype Clone()
        {

            Console.WriteLine(

              "Cloning color RGB: {0,3},{1,3},{2,3}",

              _red, _green, _blue);



            return this.MemberwiseClone() as ColorPrototype;

        }

    }
    class ColorManager
    {

        private Dictionary<string, ColorPrototype> _colors =

          new Dictionary<string, ColorPrototype>();



        // Indexer

        public ColorPrototype this[string key]
        {

            get { return _colors[key]; }

            set { _colors.Add(key, value); }

        }

    }
}
